package com.zhiwei.msf.gateway.service.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import org.apache.ibatis.session.RowBounds;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.netflix.zuul.filters.Route;
import org.springframework.cloud.netflix.zuul.filters.RouteLocator;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import com.zhiwei.msf.common.constant.DatabaseConstants;
import com.zhiwei.msf.common.dto.PageDataDto;
import com.zhiwei.msf.common.util.BeanConverterUtil;
import com.zhiwei.msf.common.util.SqlUtil;
import com.zhiwei.msf.common.util.UuidUtil;
import com.zhiwei.msf.gateway.dao.entity.RouteInfo;
import com.zhiwei.msf.gateway.dao.entity.RouteInfoExample;
import com.zhiwei.msf.gateway.dao.entity.UserInfo;
import com.zhiwei.msf.gateway.dao.mapper.RouteInfoMapper;
import com.zhiwei.msf.gateway.dao.mapper.extmapper.ExtRouteInfoMapper;
import com.zhiwei.msf.gateway.dto.QueryRouteInfoDto;
import com.zhiwei.msf.gateway.dto.RouteInfoDto;
import com.zhiwei.msf.gateway.service.RouteInfoService;
import com.zhiwei.msf.gateway.service.UserInfoService;

import lombok.extern.slf4j.Slf4j;

/**
 * function: 路由服务实现类
 * author: zhiwei_yang
 * time: 2020/2/14-11:14
 */
@Service
@Slf4j
public class RouteInfoServiceImpl implements RouteInfoService, InitializingBean {

    @Autowired
    private ExtRouteInfoMapper extRouteInfoMapper;
    @Autowired
    private RouteInfoMapper routeInfoMapper;
    @Autowired
    private RouteLocator routeLocator;
    @Autowired
    private UserInfoService userService;

    @Override
    @Transactional
    public void loadServiceRouteToDB() {
        List<Route> routeList = routeLocator.getRoutes();
        if (CollectionUtils.isEmpty(routeList)) {
            return;
        }
        List<RouteInfo> routeInfos = new ArrayList<>(routeList.size());
        UserInfo userInfo = userService.getDefaultUserInfo();
        Date nowTime = new Date();
        for (Route route : routeList) {
            RouteInfo routeInfo = new RouteInfo();
            routeInfo.setId(UuidUtil.getUUID());
            routeInfo.setPath(route.getFullPath());
            routeInfo.setRouteType(route.getLocation().startsWith("http") ? 1 : 0);
            routeInfo.setLocation(route.getLocation());
            routeInfo.setStripPrefix(route.isPrefixStripped());
            routeInfo.setRetryable(route.getRetryable());
            routeInfo.setSensitiveHeader(StringUtils.collectionToCommaDelimitedString(route.getSensitiveHeaders()));
            routeInfo.setCustomSensitiveHeader(route.isCustomSensitiveHeaders());
            routeInfo.setEnableFlag(DatabaseConstants.ENABLE);
            routeInfo.setCreateUser(userInfo.getUsername());
            routeInfo.setUpdateUser(userInfo.getUsername());
            routeInfo.setCreateTime(nowTime);
            routeInfo.setUpdateTime(nowTime);
            routeInfos.add(routeInfo);
        }
        log.info("待同步数据库路由信息 routeInfos ==> {}", routeInfos);
        extRouteInfoMapper.batchInsertOrUpdate(routeInfos);
    }

    @Override
    public PageDataDto<RouteInfoDto> queryRoutInfoByPage(QueryRouteInfoDto queryRouteInfoDto) {
        RouteInfoExample routeInfoExample = new RouteInfoExample();
        RouteInfoExample.Criteria criteria = routeInfoExample.createCriteria();
        if (null != queryRouteInfoDto.getRouteType()) {
            criteria.andRouteTypeEqualTo(queryRouteInfoDto.getRouteType());
        }
        if (!StringUtils.isEmpty(queryRouteInfoDto.getPath())) {
            criteria.andPathLike(SqlUtil.getLikeSplit(queryRouteInfoDto.getPath()));
        }
        if (!StringUtils.isEmpty(queryRouteInfoDto.getLocation())) {
            criteria.andLocationLike(queryRouteInfoDto.getLocation());
        }
        if (null != queryRouteInfoDto.getEnableFlag()) {
            criteria.andEnableFlagEqualTo(queryRouteInfoDto.getEnableFlag());
        }

        PageDataDto<RouteInfoDto> pageDataDto = new PageDataDto<>();
        int total = routeInfoMapper.countByExample(routeInfoExample);
        pageDataDto.setRowCount(total);
        pageDataDto.setPageNow(queryRouteInfoDto.getPageNow());
        pageDataDto.setPageCount(total % queryRouteInfoDto.getPageSize() == 0 ? total / queryRouteInfoDto.getPageSize() :
                total / queryRouteInfoDto.getPageSize() + 1);
        if (0 == total) {
            pageDataDto.setData(Collections.emptyList());
            log.info("路由信息分页查询为空 queryRouteInfoDto==> {}", queryRouteInfoDto);
            return pageDataDto;
        }
        RowBounds rowBounds = new RowBounds((queryRouteInfoDto.getPageNow() - 1) * queryRouteInfoDto.getPageSize(),
                queryRouteInfoDto.getPageSize());
        List<RouteInfo> routeInfoList = extRouteInfoMapper.selectByExampleByPage(routeInfoExample, rowBounds);
        pageDataDto.setData(BeanConverterUtil.convertToBeanList(routeInfoList, RouteInfoDto.class));
        log.info("路由信息分页查询为空 queryRouteInfoDto:[{}],pageDataDto ==> {}", queryRouteInfoDto, pageDataDto);
        return pageDataDto;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        loadServiceRouteToDB();
    }
}